Requirements
- loading libraries
dplyr, ggplot2,
tidyr, Hmisc
Sample overview
Data import
- Checking if result file(s) are available:
- Importing result table(s):
[1] "Import of counts table complete."
Quality control
Total number of
mapped reads per sample
- figure shows the total number of mapped reads used for fitness score
calculation
- all other reads that were filtered out during preprocessing (low
quality, low mapping score) are not included

Number of individual
barcodes per sample
- figure shows the number of individual, unique barcodes per
sample
- depnding on
bowtie settings, a certain number of
mismatches in barcodes are allowed

Number of missing
barcodes per sample
- figure shows the number of missing barcodes per sample
- this number is determined from the number of total encountered
barcodes across all samples

Number of barcodes
per gene, per sample
- figure shows the number of barcodes per gene, per sample
- the x-axis shows the number of genes with N barcodes, broken down by
sample
- barcodes without mapped reads for the respective sample are
removed
- for example a colored bar with label
≤ 2 shows number
of genes with less or equal than 2 barcodes

Read count
distribution, violin plot
- figure shows the read count distribution per sample and barcode
- read count per barcode is only shown for the first 1000 barcodes to
reduce processing time
- barcodes without mapped reads for the respective sample are
removed
- read count is log 10 transformed (0 -> 1, 1 -> 10, 2 ->
100, …)

Read count
distribution, histogram
- figure shows the same data as above, but with full set of barcodes
per sample
- barcodes without mapped reads for the respective sample are
removed
- read count is log 10 transformed (0 -> 1, 1 -> 10, 2 ->
100, …)

Top 10 most abundant
barcodes, per sample
- figure shows top 10 barcodes ranked by read count
- ideally, initial time point samples show high equality of barcode
abundance
- extremely high abundance of very few barcodes is a sign of few
mutants outcompeting the population
- this can happen when libraries are (pre-) cultivated for too long
periods of time
- can lead to downstream problems as it reduces library diversity
(depletes low abundant mutants)

Cumulative read count
distribution and barcode diversity
- figure shows the barcode diversity by plotting fraction of reads (%)
vs fraction of barcodes (%)
- the ideal library has high diversity and equal distribution of
barcodes for initial time points
- such a distribution would follow the diagonal dashed grey line
- if reads per barcode (red line) are not well distributed,
% of reads (y-axis) shows a steep ascent
- this means very few barcodes contribute to almost all reads

- this table shows the area under curve (AUC) for the line plot
above
- an AUC of 0.5 is ideal, an AUC approaching 1.0 is not optimal
- the ‘Gini index’ is a score between 0 and 1 measuring population
equality
- it is defined as the
(AUC - AUC_optimal) / AUC_optimal
- a Gini score of 0 describes a perfectly equal, a Gini score of 1.0 a
perfectly unequal distribution
Sample and replicate
correlation coefficent (R)
- figure shows heat map with correlation coefficient R (-1 < R <
1)
- correlation coefficient shows how strongly read abundance is
correlated

Sample and replicate
similarity with PCA
- this figure shows sample similarity similar to above figure
- uses principal component analysis (PCA) to reduce the
multidimensional data to 3 main dimensions
- plotted are principal component 1 (x-axis), 2 (y-axis) and 3 (point
size)
- replicates for same samples should cluster together
- outliers should be easily visible

Report info
The template for this report is located in
./nf-core-crispriscreen/bin/counts_summary.Rmd.
Date: 2024-04-10
Author: Michael Jahn, PhD
Affilations:
- Science For Life Laboratory (KTH), Stockholm, Sweden
- Max-Planck-Unit for the Science of Pathogens, Berlin, Germany
Session Info
R version 4.3.3 (2024-02-29)
Platform: x86_64-conda-linux-gnu (64-bit)
Running under: Ubuntu 20.04.6 LTS
Matrix products: default
BLAS/LAPACK: /conda-env/fitness/lib/libopenblasp-r0.3.27.so; LAPACK version 3.12.0
locale:
[1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
[4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
[7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
time zone: NA
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Hmisc_5.1-2 tidyr_1.3.1 ggplot2_3.5.0 dplyr_1.1.4
loaded via a namespace (and not attached):
[1] sass_0.4.9 utf8_1.2.4 generics_0.1.3 stringi_1.8.3
[5] digest_0.6.35 magrittr_2.0.3 evaluate_0.23 grid_4.3.3
[9] fastmap_1.1.1 jsonlite_1.8.8 nnet_7.3-19 backports_1.4.1
[13] Formula_1.2-5 gridExtra_2.3 purrr_1.0.2 fansi_1.0.6
[17] scales_1.3.0 jquerylib_0.1.4 cli_3.6.2 rlang_1.1.3
[21] munsell_0.5.1 base64enc_0.1-3 withr_3.0.0 cachem_1.0.8
[25] yaml_2.3.8 tools_4.3.3 checkmate_2.3.0 htmlTable_2.4.2
[29] colorspace_2.1-0 vctrs_0.6.5 R6_2.5.1 rpart_4.1.23
[33] lifecycle_1.0.4 stringr_1.5.1 htmlwidgets_1.6.4 foreign_0.8-86
[37] cluster_2.1.6 pkgconfig_2.0.3 pillar_1.9.0 bslib_0.7.0
[41] gtable_0.3.4 glue_1.7.0 data.table_1.15.2 highr_0.10
[45] xfun_0.43 tibble_3.2.1 tidyselect_1.2.0 rstudioapi_0.16.0
[49] knitr_1.46 farver_2.1.1 htmltools_0.5.8.1 rmarkdown_2.26
[53] labeling_0.4.3 compiler_4.3.3
LS0tCnRpdGxlOiBSZWFkIGNvdW50cyBzdW1tYXJ5CmF1dGhvcjogJ1NZU1RFTTogYHIgdmVyc2lvblsxM11gJwpkYXRlOiAnREFURTogYHIgU3lzLnRpbWUoKWAnCnBhcmFtczoKICBjcHVzOiAyCiAgYXJ0aWZhY3RfZGlyOiBhcnRpZmFjdHMKICBpbnB1dF9kaXI6IC4vCiAgbWV0YToKICAgIHZhbHVlOgogICAgICBpZDogY291bnRzX3N1bW1hcnkKICB0ZXN0OiBzb21ldmFsdWUKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSkKYGBgCgojIFJlcXVpcmVtZW50cwoKLSBsb2FkaW5nIGxpYnJhcmllcyBgZHBseXJgLCBgZ2dwbG90MmAsIGB0aWR5cmAsIGBIbWlzY2AKCmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogICAgbGlicmFyeShnckRldmljZXMpCiAgICBsaWJyYXJ5KGRwbHlyKQogICAgbGlicmFyeShnZ3Bsb3QyKQogICAgbGlicmFyeSh0aWR5cikKICAgIGxpYnJhcnkoSG1pc2MpCn0pCmBgYAoKIyBTYW1wbGUgb3ZlcnZpZXcKCiMjIERhdGEgaW1wb3J0CgotIENoZWNraW5nIGlmIHJlc3VsdCBmaWxlKHMpIGFyZSBhdmFpbGFibGU6CgpgYGB7cn0KIyBnZXQgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeQp3ZCA8LSBnZXR3ZCgpCmlucHV0X3BhdHRlcm4gPC0gImFsbF9jb3VudHMudHN2IgoKIyBjaGVjayBpbnB1dCBmaWxlcyBhbmQgY29tcGlsZSBzbWFsbCB0YWJsZQppbnB1dF9maWxlcyA8LSBncmVwKGxpc3QuZmlsZXMod2QpLCBwYXR0ZXJuID0gaW5wdXRfcGF0dGVybiwgdmFsdWUgPSBUUlVFKQppZiAobGVuZ3RoKGlucHV0X2ZpbGVzKSA9PSAxKSB7CiAgICBkZl9pbnB1dCA8LSBiaW5kX2NvbHMoCiAgICAgICAgZGF0YS5mcmFtZShpbnB1dF9maWxlcyksCiAgICAgICAgZmlsZS5pbmZvKHBhc3RlKHdkLCBpbnB1dF9maWxlcywgc2VwID0gIi8iKSkKICAgICkgJT4lCiAgICAgICAgbXV0YXRlKHNpemUgPSBwYXN0ZShzaXplIC8gMWU2LCAiTUIiKSkKICAgIHJvd25hbWVzKGRmX2lucHV0KSA8LSBOVUxMCiAgICBkZl9pbnB1dFtjKDEsIDIsIDMsIDQsIDUsIDEwKV0KfSBlbHNlIHsKICAgIHN0b3AocGFzdGUwKCJSZXF1aXJlZCBpbnB1dCBmaWxlKHMpICciLCBpbnB1dF9wYXR0ZXJuLCAiJyB3ZXJlIG5vdCBmb3VuZC4iKSkKfQpgYGAKCi0gSW1wb3J0aW5nIHJlc3VsdCB0YWJsZShzKToKCmBgYHtyfQojIGxvYWQgY291bnRzIG1hdHJpeApkZl9jb3VudHMgPC0gcmVhZC5kZWxpbShwYXN0ZTAod2QsICIvIiwgaW5wdXRfcGF0dGVybikpCmRmX2NvdW50cyA8LSB0aWR5cjo6cGl2b3RfbG9uZ2VyKGRmX2NvdW50cywKICAgIGNvbHMgPSAzOm5jb2woZGZfY291bnRzKSwKICAgIG5hbWVzX3RvID0gInNhbXBsZSIsIHZhbHVlc190byA9ICJuX3JlYWRzIgopCiMgc29ydApkZl9jb3VudHMgPC0gYXJyYW5nZShkZl9jb3VudHMsIHNhbXBsZSkKcHJpbnQoIkltcG9ydCBvZiBjb3VudHMgdGFibGUgY29tcGxldGUuIikKYGBgCgojIyBTYW1wbGUgdGFibGUKCi0gb3ZlcnZpZXcgb2Ygc2FtcGxlcwoKYGBge3J9CiMgbGlzdCBvZiBzYW1wbGVzICsgZ2VuZXJpYyBvcHRpb25zCmxpc3Rfc2FtcGxlcyA8LSB1bmlxdWUoZGZfY291bnRzJHNhbXBsZSkKZmlnd2lkdGggPC0gOQpmaWdoZWlnaHQgPC0gcm91bmQoMSArIChsZW5ndGgobGlzdF9zYW1wbGVzKSAvIDQpKQpmaWdoZWlnaHQyIDwtIDEuNiAqIGZpZ2hlaWdodAoKIyBvdXRwdXQgc2FtcGxlIHRhYmxlCnRlc3QgPC0gZGZfY291bnRzICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKAogICAgICAgIGJhcmNvZGVzID0gbGVuZ3RoKHVuaXF1ZShzZ1JOQSkpLAogICAgICAgIHRvdGFsX3JlYWRzID0gc3VtKG5fcmVhZHMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgbWluX3JlYWRzID0gbWluKG5fcmVhZHMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgbWVhbl9yZWFkcyA9IG1lYW4obl9yZWFkcywgbmEucm0gPSBUUlVFKSwKICAgICAgICBtYXhfcmVhZHMgPSBtYXgobl9yZWFkcywgbmEucm0gPSBUUlVFKSwKICAgICkKYGBgCgojIFF1YWxpdHkgY29udHJvbAoKYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0KIyBkZWZpbmUgYSBjdXN0b20gZ2dwbG90MiB0aGVtZSAoanVzdCBmb3IgcHJldHRpbmVzcykKIyBjdXN0b20gZ2dwbG90MiB0aGVtZSB0aGF0IGlzIHJldXNlZCBmb3IgYWxsIGxhdGVyIHBsb3RzCmN1c3RvbV9jb2xvcnMgPC0gYygiI0U3Mjk4QSIsICIjNjZBNjFFIiwgIiNFNkFCMDIiLCAiIzc1NzBCMyIsICIjQjNCM0IzIiwgIiMxQjlFNzciLCAiI0Q5NUYwMiIsICIjQTY3NjFEIikKY3VzdG9tX3JhbmdlIDwtIGZ1bmN0aW9uKG4gPSA1KSB7CiAgICBjb2xvclJhbXBQYWxldHRlKGN1c3RvbV9jb2xvcnNbYygxLCA1LCAyKV0pKG4pCn0KCmN1c3RvbV90aGVtZSA8LSBmdW5jdGlvbihiYXNlX3NpemUgPSAxMiwgYmFzZV9saW5lX3NpemUgPSAxLjAsIGJhc2VfcmVjdF9zaXplID0gMS4wLCAuLi4pIHsKICAgIHRoZW1lX2xpZ2h0KGJhc2Vfc2l6ZSA9IGJhc2Vfc2l6ZSwgYmFzZV9saW5lX3NpemUgPSBiYXNlX2xpbmVfc2l6ZSwgYmFzZV9yZWN0X3NpemUgPSBiYXNlX3JlY3Rfc2l6ZSkgKyB0aGVtZSgKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBncmV5KDAuNCksIHNpemUgPSAxMCksCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMTIsIDEyLCAxMiwgMTIpLCAicG9pbnRzIiksCiAgICAgICAgYXhpcy50aWNrcy5sZW5ndGggPSB1bml0KDAuMiwgImNtIiksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBncmV5KDAuNCksIGxpbmV0eXBlID0gInNvbGlkIiwgbGluZWVuZCA9ICJyb3VuZCIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IGdyZXkoMC40KSwgc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBncmV5KDAuNCksIHNpemUgPSAxMCksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMC42LCBsaW5ldHlwZSA9ICJzb2xpZCIsIGNvbG91ciA9IGdyZXkoMC45KSksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QobGluZXR5cGUgPSAic29saWQiLCBjb2xvdXIgPSBncmV5KDAuNCksIGZpbGwgPSBOQSwgc2l6ZSA9IDEuMCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gZ3JleSgwLjQpLCBzaXplID0gMTAsIG1hcmdpbiA9IHVuaXQocmVwKDMsIDQpLCAicG9pbnRzIikpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IGdyZXkoMC40KSwgc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgLi4uCiAgICApCn0KCiMgZnVuY3Rpb24gdG8gZXhwb3J0IGFuIGltYWdlIGFzIHN2ZyBhbmQgcG5nCnNhdmVfcGxvdCA8LSBmdW5jdGlvbihwbCwgcGF0aCA9ICIiLCB3aWR0aCA9IDYsIGhlaWdodCA9IDYpIHsKICAgIHBsX25hbWUgPC0gZGVwYXJzZShzdWJzdGl0dXRlKHBsKSkKICAgIHBkZigKICAgICAgICBmaWxlID0gcGFzdGUwKHBhdGgsIHBsX25hbWUsICIucGRmIiksCiAgICAgICAgd2lkdGggPSB3aWR0aCwgaGVpZ2h0ID0gaGVpZ2h0CiAgICApCiAgICBwcmludChwbCkKICAgIGRldi5vZmYoKQogICAgZ3JEZXZpY2VzOjpzdmcoCiAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAocGF0aCwgcGxfbmFtZSwgIi5zdmciKSwKICAgICAgICB3aWR0aCA9IHdpZHRoLCBoZWlnaHQgPSBoZWlnaHQKICAgICkKICAgIHByaW50KHBsKQogICAgZGV2Lm9mZigpCiAgICBnckRldmljZXM6OnBuZygKICAgICAgICBmaWxlbmFtZSA9IHBhc3RlMChwYXRoLCBwbF9uYW1lLCAiLnBuZyIpLAogICAgICAgIHdpZHRoID0gd2lkdGggKiAxMjUsIGhlaWdodCA9IGhlaWdodCAqIDEyNSwgcmVzID0gMTIwCiAgICApCiAgICBwcmludChwbCkKICAgIGludmlzaWJsZShjYXB0dXJlLm91dHB1dChkZXYub2ZmKCkpKQp9CmBgYAoKIyMgVG90YWwgbnVtYmVyIG9mIG1hcHBlZCByZWFkcyBwZXIgc2FtcGxlCgotIGZpZ3VyZSBzaG93cyB0aGUgdG90YWwgbnVtYmVyIG9mIG1hcHBlZCByZWFkcyB1c2VkIGZvciBmaXRuZXNzIHNjb3JlIGNhbGN1bGF0aW9uCi0gYWxsIG90aGVyIHJlYWRzIHRoYXQgd2VyZSBmaWx0ZXJlZCBvdXQgZHVyaW5nIHByZXByb2Nlc3NpbmcgKGxvdyBxdWFsaXR5LCBsb3cgbWFwcGluZyBzY29yZSkgYXJlIG5vdCBpbmNsdWRlZAoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfdG90YWxfbWFwcGVkX3JlYWRzIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShuX3JlYWRzID0gc3VtKG5fcmVhZHMpKSAlPiUKICAgIGdncGxvdChhZXMoeCA9IHNhbXBsZSwgeSA9IG5fcmVhZHMpKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgZ2VvbV9jb2woZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sIGFscGhhID0gMC43KSArCiAgICBsYWJzKHggPSAiIiwgeSA9ICJ0b3RhbCBudW1iZXIgb2YgbWFwcGVkIHJlYWRzIikgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X3RvdGFsX21hcHBlZF9yZWFkcywgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X3RvdGFsX21hcHBlZF9yZWFkcykKYGBgCgojIyBOdW1iZXIgb2YgaW5kaXZpZHVhbCBiYXJjb2RlcyBwZXIgc2FtcGxlCgotIGZpZ3VyZSBzaG93cyB0aGUgbnVtYmVyIG9mIGluZGl2aWR1YWwsIHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlCi0gZGVwbmRpbmcgb24gYGJvd3RpZWAgc2V0dGluZ3MsIGEgY2VydGFpbiBudW1iZXIgb2YgbWlzbWF0Y2hlcyBpbiBiYXJjb2RlcyBhcmUgYWxsb3dlZAoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfaW5kaXZpZHVhbF9iYXJjb2RlcyA8LSBkZl9jb3VudHMgJT4lCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2FtcGxlKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoYHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlYCA9IHN1bShuX3JlYWRzID4gMCkpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlLCB5ID0gYHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlYCkpICsKICAgIGdlb21fY29sKGZpbGwgPSBjdXN0b21fY29sb3JzWzFdLCBhbHBoYSA9IDAuNykgKwogICAgbGFicyh4ID0gIiIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfaW5kaXZpZHVhbF9iYXJjb2Rlcywgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X2luZGl2aWR1YWxfYmFyY29kZXMpCmBgYAoKIyMgTnVtYmVyIG9mIG1pc3NpbmcgYmFyY29kZXMgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdGhlIG51bWJlciBvZiBtaXNzaW5nIGJhcmNvZGVzIHBlciBzYW1wbGUKLSB0aGlzIG51bWJlciBpcyBkZXRlcm1pbmVkIGZyb20gdGhlIG51bWJlciBvZiB0b3RhbCBlbmNvdW50ZXJlZCBiYXJjb2RlcyBhY3Jvc3MgYWxsIHNhbXBsZXMKCmBgYHtyLCBmaWcud2lkdGggPSBmaWd3aWR0aCwgZmlnLmhlaWdodCA9IGZpZ2hlaWdodCwgd2FybmluZyA9IEZBTFNFfQpwbG90X21pc3NpbmdfYmFyY29kZXMgPC0gZGZfY291bnRzICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGBtaXNzaW5nIGJhcmNvZGVzIHBlciBzYW1wbGVgID0gc3VtKG5fcmVhZHMgPT0gMCkpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlLCB5ID0gYG1pc3NpbmcgYmFyY29kZXMgcGVyIHNhbXBsZWApKSArCiAgICBnZW9tX2NvbChmaWxsID0gY3VzdG9tX2NvbG9yc1sxXSwgYWxwaGEgPSAwLjcpICsKICAgIGxhYnMoeCA9ICIiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X21pc3NpbmdfYmFyY29kZXMsIHdpZHRoID0gZmlnd2lkdGgsIGhlaWdodCA9IGZpZ2hlaWdodCkKcHJpbnQocGxvdF9taXNzaW5nX2JhcmNvZGVzKQpgYGAKCiMjIE51bWJlciBvZiBiYXJjb2RlcyBwZXIgZ2VuZSwgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdGhlIG51bWJlciBvZiBiYXJjb2RlcyBwZXIgZ2VuZSwgcGVyIHNhbXBsZQotIHRoZSB4LWF4aXMgc2hvd3MgdGhlIG51bWJlciBvZiBnZW5lcyB3aXRoIE4gYmFyY29kZXMsIGJyb2tlbiBkb3duIGJ5IHNhbXBsZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSBmb3IgZXhhbXBsZSBhIGNvbG9yZWQgYmFyIHdpdGggbGFiZWwgYOKJpCAyYCBzaG93cyBudW1iZXIgb2YgZ2VuZXMgd2l0aCBsZXNzIG9yIGVxdWFsIHRoYW4gMiBiYXJjb2RlcwoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CmRmX2JhcmNvZGVzX3Blcl9nZW5lIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpmaWx0ZXIobl9yZWFkcyA+IDApICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSwgR2VuZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGB1bmlxdWUgYmFyY29kZXNgID0gbGVuZ3RoKHVuaXF1ZShzZ1JOQSkpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoYHVuaXF1ZSBiYXJjb2Rlc2AgPSBjdXQoYHVuaXF1ZSBiYXJjb2Rlc2AsIGJyZWFrcyA9IHByZXR0eShgdW5pcXVlIGJhcmNvZGVzYCkpKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OmNvdW50KGB1bmlxdWUgYmFyY29kZXNgKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoYHVuaXF1ZSBiYXJjb2Rlc2AgPSBhcy5udW1lcmljKGdzdWIoIlxcKFswLTldKix8XFxdIiwgIiIsIGB1bmlxdWUgYmFyY29kZXNgKSkpICU+JQogICAgZHBseXI6OnVuZ3JvdXAoKSAlPiUKICAgIGRwbHlyOjphcnJhbmdlKHNhbXBsZSwgbikKCnBsb3RfYmFyY29kZXNfZ2VuZV9zYW1wbGUgPC0gZGZfYmFyY29kZXNfcGVyX2dlbmUgJT4lCiAgICBnZ3Bsb3QoYWVzKAogICAgICAgIHggPSBzYW1wbGUsIHkgPSBuLAogICAgICAgIGZpbGwgPSBmYWN0b3IoYHVuaXF1ZSBiYXJjb2Rlc2ApLAogICAgICAgIGxhYmVsID0gcGFzdGUwKCLiiaQgIiwgYHVuaXF1ZSBiYXJjb2Rlc2ApCiAgICApKSArCiAgICBnZW9tX2NvbChhbHBoYSA9IDAuNykgKwogICAgZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIpICsKICAgIGxhYnMoeCA9ICIiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JSYW1wUGFsZXR0ZSgKICAgICAgICBjdXN0b21fY29sb3JzWzE6NV0pKGxlbmd0aCh1bmlxdWUoZGZfYmFyY29kZXNfcGVyX2dlbmVbWyJ1bmlxdWUgYmFyY29kZXMiXV0pKSkKICAgICkgKwogICAgY3VzdG9tX3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnNhdmVfcGxvdChwbG90X2JhcmNvZGVzX2dlbmVfc2FtcGxlLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQpCnByaW50KHBsb3RfYmFyY29kZXNfZ2VuZV9zYW1wbGUpCmBgYAoKIyMgUmVhZCBjb3VudCBkaXN0cmlidXRpb24sIHZpb2xpbiBwbG90CgotIGZpZ3VyZSBzaG93cyB0aGUgcmVhZCBjb3VudCBkaXN0cmlidXRpb24gcGVyIHNhbXBsZSBhbmQgYmFyY29kZQotIHJlYWQgY291bnQgcGVyIGJhcmNvZGUgaXMgb25seSBzaG93biBmb3IgdGhlIGZpcnN0IDEwMDAgYmFyY29kZXMgdG8gcmVkdWNlIHByb2Nlc3NpbmcgdGltZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSByZWFkIGNvdW50IGlzIGxvZyAxMCB0cmFuc2Zvcm1lZCAoMCAtPiAxLCAxIC0+IDEwLCAyIC0+IDEwMCwgLi4uKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfY291bnRfZGlzdCA8LSBkZl9jb3VudHMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKG5fcmVhZHMgPiAwKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OnNsaWNlKDE6MTAwMCkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBzYW1wbGUsIHkgPSBsb2cxMChuX3JlYWRzKSkpICsKICAgIGdlb21fdmlvbGluKAogICAgICAgIHRyaW0gPSBGQUxTRSwgZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sCiAgICAgICAgYWxwaGEgPSAwLjcsIGNvbCA9ICJ3aGl0ZSIKICAgICkgKwogICAgbGFicyh5ID0gZXhwcmVzc2lvbigibG9nIlsxMF0gKiAiIHJlYWRzIHBlciBiYXJjb2RlIikpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NkbCwgZ2VvbSA9ICJwb2ludHJhbmdlIiwgc2l6ZSA9IDAuNSwgY29sID0gZ3JleSgwLjMpKSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfY291bnRfZGlzdCwgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X2NvdW50X2Rpc3QpCmBgYAoKIyMgUmVhZCBjb3VudCBkaXN0cmlidXRpb24sIGhpc3RvZ3JhbQoKLSBmaWd1cmUgc2hvd3MgdGhlIHNhbWUgZGF0YSBhcyBhYm92ZSwgYnV0IHdpdGggZnVsbCBzZXQgb2YgYmFyY29kZXMgcGVyIHNhbXBsZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSByZWFkIGNvdW50IGlzIGxvZyAxMCB0cmFuc2Zvcm1lZCAoMCAtPiAxLCAxIC0+IDEwLCAyIC0+IDEwMCwgLi4uKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0Miwgd2FybmluZyA9IEZBTFNFfQpwbG90X3JlYWRzX3Blcl9iYyA8LSBkZl9jb3VudHMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBsb2cxMChuX3JlYWRzKSkpICsKICAgIGdlb21faGlzdG9ncmFtKGZpbGwgPSBjdXN0b21fY29sb3JzWzFdLCBhbHBoYSA9IDAuNywgYmlucyA9IDMwKSArCiAgICBsYWJzKHkgPSAiIiwgeCA9IGV4cHJlc3Npb24oImxvZyJbMTBdICogIiByZWFkcyBwZXIgYmFyY29kZSIpKSArCiAgICBmYWNldF93cmFwKH5zYW1wbGUsIG5jb2wgPSA0KSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfcmVhZHNfcGVyX2JjLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQyKQpwcmludChwbG90X3JlYWRzX3Blcl9iYykKYGBgCgojIyBUb3AgMTAgbW9zdCBhYnVuZGFudCBiYXJjb2RlcywgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdG9wIDEwIGJhcmNvZGVzIHJhbmtlZCBieSByZWFkIGNvdW50Ci0gaWRlYWxseSwgaW5pdGlhbCB0aW1lIHBvaW50IHNhbXBsZXMgc2hvdyBoaWdoIGVxdWFsaXR5IG9mIGJhcmNvZGUgYWJ1bmRhbmNlCi0gZXh0cmVtZWx5IGhpZ2ggYWJ1bmRhbmNlIG9mIHZlcnkgZmV3IGJhcmNvZGVzIGlzIGEgc2lnbiBvZiBmZXcgbXV0YW50cyBvdXRjb21wZXRpbmcgdGhlIHBvcHVsYXRpb24KLSB0aGlzIGNhbiBoYXBwZW4gd2hlbiBsaWJyYXJpZXMgYXJlIChwcmUtKSBjdWx0aXZhdGVkIGZvciB0b28gbG9uZyBwZXJpb2RzIG9mIHRpbWUKLSBjYW4gbGVhZCB0byBkb3duc3RyZWFtIHByb2JsZW1zIGFzIGl0IHJlZHVjZXMgbGlicmFyeSBkaXZlcnNpdHkgKGRlcGxldGVzIGxvdyBhYnVuZGFudCBtdXRhbnRzKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0Miwgd2FybmluZyA9IEZBTFNFfQpwbG90X3RvcDEwX2JhcmNvZGVzIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OmFycmFuZ2Uoc2FtcGxlLCBkZXNjKG5fcmVhZHMpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUocmFuayA9IHNlcV9hbG9uZyhzZ1JOQSkpICU+JQogICAgZHBseXI6OmZpbHRlcihiZXR3ZWVuKHJhbmssIDEsIDEwKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IocmFuayksIHkgPSBuX3JlYWRzKSkgKwogICAgZ2VvbV9jb2woZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sIGFscGhhID0gMC43LCB3aWR0aCA9IDEpICsKICAgIGxhYnMoeSA9ICJuIHJlYWRzIiwgeCA9ICJiYXJjb2RlcyByYW5rZWQgYnkgYWJ1bmRhbmNlIikgKwogICAgZmFjZXRfd3JhcCh+c2FtcGxlLCBuY29sID0gNCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X3RvcDEwX2JhcmNvZGVzLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQyKQpwcmludChwbG90X3RvcDEwX2JhcmNvZGVzKQpgYGAKCiMjIEN1bXVsYXRpdmUgcmVhZCBjb3VudCBkaXN0cmlidXRpb24gYW5kIGJhcmNvZGUgZGl2ZXJzaXR5CgotIGZpZ3VyZSBzaG93cyB0aGUgYmFyY29kZSBkaXZlcnNpdHkgYnkgcGxvdHRpbmcgZnJhY3Rpb24gb2YgcmVhZHMgKCUpIHZzIGZyYWN0aW9uIG9mIGJhcmNvZGVzICglKQotIHRoZSBpZGVhbCBsaWJyYXJ5IGhhcyBoaWdoIGRpdmVyc2l0eSBhbmQgZXF1YWwgZGlzdHJpYnV0aW9uIG9mIGJhcmNvZGVzIGZvciBpbml0aWFsIHRpbWUgcG9pbnRzCi0gc3VjaCBhIGRpc3RyaWJ1dGlvbiB3b3VsZCBmb2xsb3cgdGhlIGRpYWdvbmFsIGRhc2hlZCBncmV5IGxpbmUKLSBpZiByZWFkcyBwZXIgYmFyY29kZSAocmVkIGxpbmUpIGFyZSBub3Qgd2VsbCBkaXN0cmlidXRlZCwgYCUgb2YgcmVhZHNgICh5LWF4aXMpIHNob3dzIGEgc3RlZXAgYXNjZW50Ci0gdGhpcyBtZWFucyB2ZXJ5IGZldyBiYXJjb2RlcyBjb250cmlidXRlIHRvIGFsbW9zdCBhbGwgcmVhZHMKCmBgYHtyLCBmaWcud2lkdGggPSBmaWd3aWR0aCwgZmlnLmhlaWdodCA9IGZpZ2hlaWdodDIsIHdhcm5pbmcgPSBGQUxTRX0KZGZfYXVjIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjphcnJhbmdlKHNhbXBsZSwgZGVzYyhuX3JlYWRzKSkgJT4lCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2FtcGxlKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgICAgcGNfYmFyY29kZXMgPSAxMDAgKiBzZXFfYWxvbmcobl9yZWFkcykgLyBuKCksCiAgICAgICAgcGNfcmVhZHMgPSAxMDAgKiBuX3JlYWRzIC8gKHN1bShuX3JlYWRzKSkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBjX2JhcmNvZGVzID0gcm91bmQocGNfYmFyY29kZXMpKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUsIHBjX2JhcmNvZGVzKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUocGNfcmVhZHMgPSBzdW0ocGNfcmVhZHMpLCAuZ3JvdXBzID0gImRyb3BfbGFzdCIpICU+JQogICAgZHBseXI6Om11dGF0ZShwY19yZWFkcyA9IGN1bXN1bShwY19yZWFkcykpCgpwbG90X2N1bXVsYXRpdmVfcmVhZF9jb3VudCA8LSBkZl9hdWMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBwY19iYXJjb2RlcywgeSA9IHBjX3JlYWRzLCBncm91cCA9IHNhbXBsZSkpICsKICAgIGdlb21fc3RlcChsaW5ld2lkdGggPSAxLjAsIGNvbG9yID0gY3VzdG9tX2NvbG9yc1sxXSkgKwogICAgZ2VvbV9hYmxpbmUoCiAgICAgICAgc2xvcGUgPSAxLCBpbnRlcmNlcHQgPSAwLCBsaW5ld2lkdGggPSAxLjAsCiAgICAgICAgbGluZXR5cGUgPSAyLCBjb2xvciA9IGdyZXkoMC41KQogICAgKSArCiAgICBsaW1zKHggPSBjKDAsIDEwMCksIHkgPSBjKDAsIDEwMCkpICsKICAgIGxhYnMoeCA9ICIlIG9mIGJhcmNvZGVzIiwgeSA9ICIlIG9mIHJlYWRzIikgKwogICAgZmFjZXRfd3JhcCh+c2FtcGxlLCBuY29sID0gNCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X2N1bXVsYXRpdmVfcmVhZF9jb3VudCwgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0MikKcHJpbnQocGxvdF9jdW11bGF0aXZlX3JlYWRfY291bnQpCmBgYAoKLSB0aGlzIHRhYmxlIHNob3dzIHRoZSBhcmVhIHVuZGVyIGN1cnZlIChBVUMpIGZvciB0aGUgbGluZSBwbG90IGFib3ZlCi0gYW4gQVVDIG9mIDAuNSBpcyBpZGVhbCwgYW4gQVVDIGFwcHJvYWNoaW5nIDEuMCBpcyBub3Qgb3B0aW1hbAotIHRoZSAnR2luaSBpbmRleCcgaXMgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEgbWVhc3VyaW5nIHBvcHVsYXRpb24gZXF1YWxpdHkKLSBpdCBpcyBkZWZpbmVkIGFzIHRoZSBgKEFVQyAtIEFVQ19vcHRpbWFsKSAvIEFVQ19vcHRpbWFsYAotIGEgR2luaSBzY29yZSBvZiAwIGRlc2NyaWJlcyBhIHBlcmZlY3RseSBlcXVhbCwgYSBHaW5pIHNjb3JlIG9mIDEuMCBhIHBlcmZlY3RseSB1bmVxdWFsIGRpc3RyaWJ1dGlvbgoKYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0KY2FsY19hdWMgPC0gZnVuY3Rpb24oeCwgeSkgewogICAgc3VtKGRpZmYoeCkgKiAoaGVhZCh5LCAtMSkgKyB0YWlsKHksIC0xKSkpIC8gMgp9CmRmX2F1YyAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoCiAgICAgICAgYXVjID0gY2FsY19hdWMocGNfYmFyY29kZXMsIHBjX3JlYWRzKS8xMDBeMiwKICAgICAgICBhdWNfb3B0aW1hbCA9IDAuNSwKICAgICAgICBnaW5pID0gKGF1YyAtIDAuNSkgLyAwLjUKICAgICkgJT4lCiAgICBtdXRhdGUocXVhbGl0eSA9IGNhc2Vfd2hlbigKICAgICAgICBnaW5pIDw9IDAuMzMgfiAibG93IGluZXF1YWxpdHkgKEcgPCAwLjMzKSIsCiAgICAgICAgZ2luaSA+IDAuMzMgJiBnaW5pIDw9IDAuNjYgfiAiaW50ZXJtZWRpYXRlIGluZXF1YWxpdHkgKDAuMzMgPCBHIDwgMC42NikiLAogICAgICAgIGdpbmkgPiAwLjY2IH4gImhpZ2ggaW5lcXVhbGl0eSAoRyA+IDAuNjYpIgogICAgKSkKYGBgCgoKIyMgU2FtcGxlIGFuZCByZXBsaWNhdGUgY29ycmVsYXRpb24gY29lZmZpY2VudCAoUikKCi0gZmlndXJlIHNob3dzIGhlYXQgbWFwIHdpdGggY29ycmVsYXRpb24gY29lZmZpY2llbnQgUiAoLTEgPCBSIDwgMSkKLSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBzaG93cyBob3cgc3Ryb25nbHkgcmVhZCBhYnVuZGFuY2UgaXMgY29ycmVsYXRlZAoKYGBge3IsIGZpZy53aWR0aCA9IDcuNSwgZmlnLmhlaWdodCA9IDcsIHdhcm5pbmcgPSBGQUxTRX0KZGZfY29ycmVsYXRpb24gPC0gZGZfY291bnRzICU+JQogICAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAic2FtcGxlIiwgdmFsdWVzX2Zyb20gPSAibl9yZWFkcyIpICU+JQogICAgZHBseXI6OnNlbGVjdCgtYygxOjIpKSAlPiUKICAgIGNvcigpCgpwbG90X3JlcGxpY2F0ZV9jb3JyZWxhdGlvbiA8LSBkZl9jb3JyZWxhdGlvbiAlPiUKICAgIGRwbHlyOjphc190aWJibGUoKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoc2FtcGxlMSA9IGNvbG5hbWVzKC4pKSAlPiUKICAgIHRpZHlyOjpwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9ICFzYW1wbGUxLAogICAgICAgIG5hbWVzX3RvID0gInNhbXBsZTIiLCB2YWx1ZXNfdG8gPSAiY29yX2NvZWYiCiAgICApICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlMSwgeSA9IHNhbXBsZTIsIGZpbGwgPSBjb3JfY29lZikpICsKICAgIGdlb21fdGlsZSgpICsKICAgIGdlb21fdGV4dChjb2xvciA9IGdyZXkoMC40KSwgYWVzKGxhYmVsID0gcm91bmQoY29yX2NvZWYsIDIpKSkgKwogICAgY3VzdG9tX3RoZW1lKCkgKwogICAgbGFicyh0aXRsZSA9ICIiLCB4ID0gIiIsIHkgPSAiIikgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gMSkpICsKICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKAogICAgICAgIGNvbG91cnMgPSBjKGN1c3RvbV9jb2xvcnNbMV0sIGdyZXkoMC45KSwgY3VzdG9tX2NvbG9yc1syXSksCiAgICAgICAgbGltaXRzID0gYygtMSwgMSkKICAgICkKCndyaXRlLmNzdihkZl9jb3JyZWxhdGlvbiwgZmlsZSA9ICJjb3JyZWxhdGlvbl90YWJsZS5jc3YiKQpzYXZlX3Bsb3QocGxvdF9yZXBsaWNhdGVfY29ycmVsYXRpb24sIHdpZHRoID0gNy41LCBoZWlnaHQgPSA3KQpwcmludChwbG90X3JlcGxpY2F0ZV9jb3JyZWxhdGlvbikKYGBgCgojIyBTYW1wbGUgYW5kIHJlcGxpY2F0ZSBzaW1pbGFyaXR5IHdpdGggUENBCgotIHRoaXMgZmlndXJlIHNob3dzIHNhbXBsZSBzaW1pbGFyaXR5IHNpbWlsYXIgdG8gYWJvdmUgZmlndXJlCi0gdXNlcyBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpIHRvIHJlZHVjZSB0aGUgbXVsdGlkaW1lbnNpb25hbCBkYXRhIHRvIDMgbWFpbiBkaW1lbnNpb25zCi0gcGxvdHRlZCBhcmUgcHJpbmNpcGFsIGNvbXBvbmVudCAxICh4LWF4aXMpLCAyICh5LWF4aXMpIGFuZCAzIChwb2ludCBzaXplKQotIHJlcGxpY2F0ZXMgZm9yIHNhbWUgc2FtcGxlcyBzaG91bGQgY2x1c3RlciB0b2dldGhlcgotIG91dGxpZXJzIHNob3VsZCBiZSBlYXNpbHkgdmlzaWJsZQoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3LCB3YXJuaW5nID0gRkFMU0V9CnBjYV9yZXN1bHQgPC0gZGZfY291bnRzICU+JQogICAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAic2FtcGxlIiwgdmFsdWVzX2Zyb20gPSAibl9yZWFkcyIpICU+JQogICAgZHBseXI6OnNlbGVjdCgtYygxOjIpKSAlPiUKICAgIGFzLm1hdHJpeCgpICU+JQogICAgdCgpICU+JQogICAgcmVwbGFjZSguLCBpcy5uYSguKSwgMCkgJT4lCiAgICBwcmNvbXAoKQoKZGZfUENBIDwtIHBjYV9yZXN1bHQkeCAlPiUKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJzYW1wbGUiKQoKcGxvdF9yZXBsaWNhdGVfcGNhIDwtIGRmX1BDQSAlPiUKICAgIGdncGxvdChhZXMoeCA9IFBDMSwgeSA9IC1QQzIsIHNpemUgPSBQQzMsIGNvbG9yID0gc2FtcGxlLCBsYWJlbCA9IHNhbXBsZSkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcpICsKICAgIGdlb21fdGV4dChzaXplID0gMi41LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgICBsYWJzKAogICAgICAgIHRpdGxlID0gIlBDQSwgZmlyc3QgdGhyZWUgcHJpbmNpcGFsIGNvbXBvbmVudHMiLAogICAgICAgIHN1YnRpdGxlID0gIlBvaW50IHNpemUgZW5jb2RlcyBQQzMiLCB4ID0gIlBDMSIsIHkgPSAiUEMyIgogICAgKSArCiAgICBjdXN0b21fdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBhc3BlY3QucmF0aW8gPSAxKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JSYW1wUGFsZXR0ZShjdXN0b21fY29sb3JzKShucm93KGRmX1BDQSkpKSArCiAgICBndWlkZXMoc2l6ZSA9ICJub25lIikKCnNhdmVfcGxvdChwbG90X3JlcGxpY2F0ZV9wY2EsIHdpZHRoID0gNywgaGVpZ2h0ID0gNykKcHJpbnQocGxvdF9yZXBsaWNhdGVfcGNhKQpgYGAKCiMgUmVwb3J0IGluZm8KClRoZSB0ZW1wbGF0ZSBmb3IgdGhpcyByZXBvcnQgaXMgbG9jYXRlZCBpbiBgLi9uZi1jb3JlLWNyaXNwcmlzY3JlZW4vYmluL2NvdW50c19zdW1tYXJ5LlJtZGAuCgpEYXRlOiAyMDI0LTA0LTEwCgpBdXRob3I6IE1pY2hhZWwgSmFobiwgUGhECgpBZmZpbGF0aW9uczoKCi0gU2NpZW5jZSBGb3IgTGlmZSBMYWJvcmF0b3J5IChLVEgpLCBTdG9ja2hvbG0sIFN3ZWRlbgotIE1heC1QbGFuY2stVW5pdCBmb3IgdGhlIFNjaWVuY2Ugb2YgUGF0aG9nZW5zLCBCZXJsaW4sIEdlcm1hbnkKCiMgU2Vzc2lvbiBJbmZvCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAK